package com.start.avue.mapper;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.sql.Timestamp;
import java.time.*;
import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;

@Slf4j
public class AvueDateMapper extends AvueDefaultMapper {
    public static final String MAPPER_TYPE_DATE = "date";
    public static final String MAPPER_TYPE_TIME = "time";
    public static final String MAPPER_TYPE_DATE_TIME = "datetime";

    public static final Pattern RE_TIME_MILLIS = Pattern.compile("\\d{4,}$");
    private String labelDateTimeFormat;
    private String valueDateTimeFormat;


    @Override
    public void init(String startHomeUrl, JSONObject column, Map<String, String> headers) {
        super.init(startHomeUrl, column, headers);

        if (column.containsKey("format")) {
            labelDateTimeFormat = column.getString("format");
            labelDateTimeFormat = labelDateTimeFormat.replace("Y", "y").replace("D", "d");
        } else {
            labelDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            column.put("format", labelDateTimeFormat);
        }
        if (column.containsKey("valueFormat")) {
            valueDateTimeFormat = column.getString("valueFormat");
            valueDateTimeFormat = valueDateTimeFormat.replace("Y", "y").replace("D", "d");
        } else {
            valueDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            column.put("valueFormat", labelDateTimeFormat);
        }
    }

    @Override
    public Object labelToValue(String label) {
        LocalDateTime localDateTime = handlerStrToLocalTime(label);
        if (localDateTime == null) return super.labelToValue(label);
        return localDateTime;
    }


    @Override
    public Object valueToLabel(Object value) {
        if (value == null) {
            return super.valueToLabel(value);
        }
        Object format = valueToLabelFormat(value);
        if (format == null) return super.valueToLabel(value);
        return format;
    }

    private Object valueToLabelFormat(Object value) {
        try {
            LocalDateTime result = null;
            if (value instanceof Timestamp) {
                result = LocalDateTimeUtil.of((Timestamp) value);
            } else if (value instanceof LocalDateTime) {
                result = (LocalDateTime) value;
            } else if (value instanceof Date) {
                result = LocalDateTimeUtil.of((Date) value);
            } else if (value instanceof LocalDate) {
                result = LocalDateTimeUtil.of((LocalDate) value);
            } else if (value instanceof LocalTime) {
                result = LocalDateTimeUtil.of((LocalTime) value);
            } else if (value instanceof Long) {
                result = LocalDateTimeUtil.of((Long) value);
            }
            if (result != null) {
                return LocalDateTimeUtil.format(result, labelDateTimeFormat);
            }
            String tempValue = value instanceof String ? (String) value : value.toString();
            result = handlerStrToLocalTime(tempValue);
            if (result == null) {
                return null;
            }
            return LocalDateTimeUtil.format(result, labelDateTimeFormat);
        } catch (Exception e) {
            log.error("时间日期格式化错误valueToLabelFormat：" + this.getProp() + ":" + value);
            e.printStackTrace();
            return value;
        }

    }

    private LocalDateTime handlerStrToLocalTime(String value) {
        LocalDateTime result = null;
        try {
            if (value.contains("T")) {
                result = LocalDateTimeUtil.parse(value);
            } else if (RE_TIME_MILLIS.matcher(value).find()) {
                Instant timeMilli = Instant.ofEpochMilli(Long.parseLong(value));
                result = LocalDateTime.ofInstant(timeMilli, ZoneId.systemDefault());
            } else {
                result = LocalDateTimeUtil.parse(value, valueDateTimeFormat);
            }
            if (result == null) {
                result = LocalDateTimeUtil.parse(value, labelDateTimeFormat);
            }
        } catch (Exception e) {
            log.error("时间日期格式化错误labelToLocalDateTime：" + this.getProp() + ":" + value);
            e.printStackTrace();

        }
        return result;
    }


}
